using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Millis.Controls
{
    public partial class FileGrid : UserControl
    {
        #region Private Fields
        private BindingList<FileData> _files = new BindingList<FileData>();
        private bool _directoryMode = false;
        #endregion

        #region Public Properties
        /// <summary>
        /// Gets or sets the remove files string.
        /// </summary>
        /// <value>The remove files string.</value>
        public string RemoveFilesString
        {
            get { return btnRemoveFiles.Text; }
            set { btnRemoveFiles.Text = value; }
        }

        /// <summary>
        /// Gets or sets the add files string.
        /// </summary>
        /// <value>The add files string.</value>
        public string AddFilesString
        {
            get { return btnAddFiles.Text; }
            set { btnAddFiles.Text = value; }
        }

        /// <summary>
        /// Gets or sets the add folder string.
        /// </summary>
        /// <value>The add folder string.</value>
        public string AddFolderString
        {
            get { return btnAddFolder.Text; }
            set { btnAddFolder.Text = value; }
        }

        /// <summary>
        /// Gets or sets the files filter.
        /// </summary>
        /// <value>The files filter.</value>
        public string FilesFilter
        {
            get { return dlgOpenFile.Filter; }
            set { dlgOpenFile.Filter = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [remove files visible].
        /// </summary>
        /// <value><c>true</c> if [remove files visible]; otherwise, <c>false</c>.</value>
        public bool RemoveFilesVisible
        {
            get { return btnRemoveFiles.Visible; }
            set { btnRemoveFiles.Visible = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [add files visible].
        /// </summary>
        /// <value><c>true</c> if [add files visible]; otherwise, <c>false</c>.</value>
        public bool AddFilesVisible
        {
            get { return btnAddFiles.Visible; }
            set { btnAddFiles.Visible = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [add folder visible].
        /// </summary>
        /// <value><c>true</c> if [add folder visible]; otherwise, <c>false</c>.</value>
        public bool AddFolderVisible
        {
            get { return btnAddFolder.Visible; }
            set { btnAddFolder.Visible = value; }
        }

        /// <summary>
        /// Gets the file count.
        /// </summary>
        /// <value>The file count.</value>
        public int FileCount
        {
            get { return _files.Count; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [toolbar visible].
        /// </summary>
        /// <value><c>true</c> if [toolbar visible]; otherwise, <c>false</c>.</value>
        public bool ToolbarVisible
        {
            get { return toolStrip1.Visible; }
            set { toolStrip1.Visible = value; }
        }

        public bool DirectoryMode
        {
            get { return _directoryMode; }
            set { _directoryMode = value; }
        }
        #endregion

        #region Contructors
        public FileGrid()
        {
            InitializeComponent();
            AddFilesString = "&Open File(s)";
            RemoveFilesString = "&Remove File(s)";
            AddFolderString = "Open &Folder";
            fileDataBindingSource.DataSource = _files;
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Gets the file paths list.
        /// </summary>
        /// <returns></returns>
        public List<string> GetFilePathsList()
        {
            List<string> paths = new List<string>(_files.Count);
            foreach (FileData fd in _files)
                paths.Add(fd.FilePath);
            return paths;
        }

        /// <summary>
        /// Cleats the list.
        /// </summary>
        public void CleatList()
        {
            List<FileData> filesForRemoval = new List<FileData>(grdFiles.SelectedRows.Count);
            foreach (DataGridViewRow row in grdFiles.Rows)
            {
                FileData fd = row.DataBoundItem as FileData;
                if (fd != null)
                    filesForRemoval.Add(fd);
            }

            foreach (FileData fd in filesForRemoval)
                _files.Remove(fd);
        }

        /// <summary>
        /// Sets the color of the row.
        /// </summary>
        /// <param name="color">The color.</param>
        /// <param name="rowValue">The row value.</param>
        public void SetRowColor(Color color, string rowValue)
        {
            foreach (DataGridViewRow row in grdFiles.Rows)
            {
                FileData fd = row.DataBoundItem as FileData;
                if (fd != null && fd.FilePath.Equals(rowValue))
                {
                    row.DefaultCellStyle.BackColor = color;                    
                    break;
                }
            }
        }
        /// <summary>
        /// Clears the selection.
        /// </summary>
        public void ClearSelection()
        {
            foreach (DataGridViewRow row in grdFiles.Rows)
            {
                row.Selected = false;
            }
        }

        /// <summary>
        /// Clears the color of the row.
        /// </summary>
        public void ClearRowColor()
        {
            foreach (DataGridViewRow row in grdFiles.Rows)
            {
                row.DefaultCellStyle.BackColor = Color.White;
            }
        }

        /// <summary>
        /// Adds the file path.
        /// </summary>
        /// <param name="path">The path.</param>
        private void AddFilePath(string path)
        {
            FileInfo fi = new FileInfo(path);
            _files.Add(new FileData(fi.FullName, fi.Length));
        }

        /// <summary>
        /// Adds the folder path.
        /// </summary>
        /// <param name="path">The path.</param>
        public void AddFolderPath(string path)
        {
            _files.Add(new FileData(path, 0));
        }

        /// <summary>
        /// Adds the folders path.
        /// </summary>
        public void AddFoldersPath(IList<string> directoryPaths)
        {
            foreach (string path in directoryPaths)
            {
                AddFolderPath(path);
            }
        }

        /// <summary>
        /// Adds the file paths.
        /// </summary>
        /// <param name="filePaths">The file paths.</param>
        public void AddFilePaths(IList<string> filePaths)
        {
            foreach (string path in filePaths)
            {
                AddFilePath(path);
            }
        }
        #endregion

        #region Event Handlers
        /// <summary>
        /// Handles the Click event of the btnAddFiles control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnAddFiles_Click(object sender, EventArgs e)
        {
            DialogResult dr = dlgOpenFile.ShowDialog();
            if (dr == DialogResult.OK)
            {
                foreach (string filePath in dlgOpenFile.FileNames)
                {
                    FileInfo fi = new FileInfo(filePath);
                    AddFile(fi);
                }
            }
        }

        /// <summary>
        /// Handles the Click event of the btnAddFolder control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void btnAddFolder_Click(object sender, EventArgs e)
        {
            if (dlgFolderBrowser.ShowDialog() == DialogResult.OK)
            {
                if (DirectoryMode)
                {
                    _files.Add(new FileData(dlgFolderBrowser.SelectedPath, 0));
                }
                else
                {
                    DirectoryInfo di = new DirectoryInfo(dlgFolderBrowser.SelectedPath);
                    foreach (FileInfo fi in di.GetFiles())
                    {
                        AddFile(fi);
                    }
                }
            }
        }

        /// <summary>
        /// Handles the Click event of the btnRemoveFiles control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnRemoveFiles_Click(object sender, EventArgs e)
        {
            List<FileData> filesForRemoval = new List<FileData>(grdFiles.SelectedRows.Count);
            foreach (DataGridViewRow row in grdFiles.SelectedRows)
            {
                FileData fd = row.DataBoundItem as FileData;
                if (fd != null)
                    filesForRemoval.Add(fd);
            }

            foreach (FileData fd in filesForRemoval)
                _files.Remove(fd);
        }
        #endregion

        #region Private Methods

        /// <summary>
        /// Adds the file.
        /// </summary>
        /// <param name="fileInfo">The file info.</param>
        private void AddFile(FileInfo fileInfo)
        {
            bool notExist = true;
            foreach (FileData fileData in _files)
                if (fileData.FilePath == fileInfo.FullName)
                    notExist = false;
            if (notExist)
                _files.Add(new FileData(fileInfo.FullName, fileInfo.Length));
        }

        #endregion
    }
}
